package com.epoint.netty.protocol;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import io.netty.handler.codec.http.*;
import io.netty.handler.logging.LoggingHandler;

import java.util.concurrent.TimeUnit;

/**
 * 模拟http的Server端（类似tomcat）
 *
 * 浏览器作为Client
 */
public class HttpServer {

    public static void main(String[] args) {
        new ServerBootstrap()
                .group(new NioEventLoopGroup())
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    // 加载处理器
                    protected void initChannel(NioSocketChannel ch) {
                        ch.pipeline().addLast(new LoggingHandler());
                        // 直接使用netty提供的http的处理器，帮我们做好了协议的 加密、解密
                        ch.pipeline().addLast(new HttpServerCodec());
                        // 正常写法
//                        ch.pipeline().addLast(new ChannelInboundHandlerAdapter(){
//                            @Override
//                            public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
//                                /**
//                                 * 会调用两次，两次返回值如下：
//                                 * io.netty.handler.codec.http.DefaultHttpRequest
//                                 * io.netty.handler.codec.http.LastHttpContent$1
//                                 */
//                                System.out.println("返回值类型：" + msg.getClass());
//                            }
//                        });
                        // 简易写法
                        ch.pipeline().addLast(new SimpleChannelInboundHandler<HttpRequest>() {
                            @Override
                            protected void channelRead0(ChannelHandlerContext channelHandlerContext, HttpRequest httpRequest) throws Exception {
                                System.out.println("请求url：" + httpRequest.getUri());

                                // 模拟处理业务代码
                                TimeUnit.SECONDS.sleep(2);

                                // 给个响应，最后我估计还是要先回到 HttpServerCodec 这个处理器，在帮我们程序员封装下write数据给客户端
                                DefaultFullHttpResponse response =
                                        new DefaultFullHttpResponse(httpRequest.protocolVersion(), HttpResponseStatus.OK);

                                byte[] bytes = ("<h1>Hello, world!  your request url: " + httpRequest.getUri() + "</h1>").getBytes();

                                response.headers().setInt(HttpHeaderNames.CONTENT_LENGTH, bytes.length);
                                response.content().writeBytes(bytes);

                                // 写回响应
                                channelHandlerContext.writeAndFlush(response);
                            }
                        });

                    }
                })
                .bind(8080);
    }

}
